package wviz.gui.graph;

import prefuse.data.Graph;
import prefuse.data.Node;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class GraphGenerator {
    public static final String WORD_COLUMN = "word";
    public static final String LINKS_COLUMN = "links";

    public static Graph pairListToGraph(List<String[]> pairList) {
        //tODO: capitalize the pairList:
        if (pairList == null || pairList.size() < 1) {
            pairList = new ArrayList<String[]>(1);
            pairList.add(new String[]{"no visualisation", "is available!"});
        } else {
            capitalize(pairList);
        }

        Node n0, n1;

        Map<String, Node> nodeMap = new HashMap<String, Node>();
        Graph g = new Graph();
        g.addColumn(WORD_COLUMN, String.class);
        g.addColumn(LINKS_COLUMN, int.class);
        for (String[] pair : pairList) {
            n0 = getNode(nodeMap, pair[0], g);
            n1 = getNode(nodeMap, pair[1], g);
            g.addEdge(n0, n1);

        }
        return g;
    }

    private static Node getNode(Map<String, Node> nodeMap, String word, Graph g) {

        Node n = nodeMap.get(word);
        int links = 1;
        if (n == null) {
            n = g.addNode();
            n.setString(WORD_COLUMN, word);
            n.setInt(LINKS_COLUMN, links);
            nodeMap.put(word, n);
        } else {
            links = n.getInt(LINKS_COLUMN);
            links++;
            n.setInt(LINKS_COLUMN, links);
            nodeMap.put(word, n);
        }

        return n;
    }


    /**
     * This method searches a list of string pairs and puts the string with more links (either input or output link) in
     * the top of the list.
     * The only actual benefit of this class is to be used before converting pairlist to prefuse graph while the first
     * node is chosen as the root of the coresponding spanning tree.
     * 
     * @param pairList list of string pairs for generating graph
     */
    public static void capitalize(List<String[]> pairList) {
        Map<String, Integer /*links*/> term_linksMap = new HashMap<String, Integer>();
        // find links of each term
        for (String[] pair : pairList) {
            for (String term : pair) {
                Integer currentLinks = term_linksMap.get(term);
                if (currentLinks == null) {
                    term_linksMap.put(term, 1);
                } else {
                    term_linksMap.put(term, currentLinks + 1);
                }
            }
        }
        // find the capital:
        int maxLinks = -1;
        String capital = null;
        for (String term : term_linksMap.keySet()) {
            int currentLinks = term_linksMap.get(term);
            if (currentLinks > maxLinks) {
                capital = term;
                maxLinks = currentLinks;
            }
        }
        if (capital == null) throw new RuntimeException();
        // put the capital in the top of the list:
        String[] firstCapitalOccuence = null;
        for (String[] pair : pairList) {
            String w1 = pair[0];
            String w2 = pair[1];
            if (w1.equals(capital) || w2.equals(capital)) {
                firstCapitalOccuence = pair;//new String[]{capital, w1.equals(capital) ? w2 : w1};
                break;
            }
        }
        if (firstCapitalOccuence == null) throw new RuntimeException();
        pairList.remove(firstCapitalOccuence);
        pairList.add(0, new String[]{capital,
                firstCapitalOccuence[0].equals(capital) ? firstCapitalOccuence[1] : firstCapitalOccuence[0]});

    }


}
